﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

// Basic global alias for the main class containing constants
using r = Rougeliek.Rougeliek;

namespace Rougeliek
{
    class UI
    {
        // Create list items for UI elements to be stored
        public static List<UIItem> ui;
        public static List<UIItem> popup = new List<UIItem>();

        // Basic command for a full redraw of the UI
        // -- VERY -- slow and choppy, avoid using unless necessary
        public static void drawUI()
        {
            // Output every item in the ui list
            foreach (UIItem item in ui)
            {
                Console.SetCursorPosition(item.uiX, item.uiY);
                Console.Write(item.uiChar);
            }

            // Draw the player's HP and MP in the bottom box
            Console.SetCursorPosition(r.SCREENMIN + 1, r.SCREENY + 2);
            Console.Write("hp: " + r.pc.hp + "/" + r.pc.maxhp + " mp: " + r.pc.mp + "/" + r.pc.maxmp);

            uiCursor();
        }

        // This is used just to refresh the UI information, can be
        // called as much as you like with no choppyness
        public static void updateUI()
        {
            Console.SetCursorPosition(r.SCREENMIN + 1, r.SCREENY + 2);
            Console.Write("hp: " + r.pc.hp + " mp: " + r.pc.mp);
        }

        // Basic menu handling, to be expanded upon when i start putting in
        // more features
        public static void menuUI(string submenu)
        {
            // Set a boolean to determine whether it's in the menu loop
            bool menuRunning = true;

            // Submenu is totally the wrong word, but these define the menu
            // type and launch a popup window which will display in the top right
            if (submenu == "inventory")
            {
                popupBox("Inventory:");

                Console.SetCursorPosition(r.SCREENMIN + 1, r.SCREENMIN + 4);

                foreach (InventoryItem item in Inventory.inventory)
                {
                    if (item.category == 1)
                    {
                        Console.Write("Consumable  : " + item.name + "\n║ ");
                    }
                    else if (item.category == 2)
                    {
                        Console.Write("Weapon      : " + item.name + "\n║ ");
                    }
                    else if (item.category == 3)
                    {
                        Console.Write("Head Armour : " + item.name + "\n║ ");
                    }
                    else if (item.category == 4)
                    {
                        Console.Write("Torso Armour: " + item.name + "\n║ ");
                    }
                    else if (item.category == 5)
                    {
                        Console.Write("Leg Armour  : " + item.name + "\n║ ");
                    }
                }

                uiCursor(;)

            }
            else if (submenu == "pause")
            {
                popupBox("Pause");
            }
            else if (submenu == "help")
            {
                popupBox("Help: (Q)uit, (R)eset, (S)tatus, (I)nventory");
            }
            else if (submenu == "status")
            {
                Random rdm = new Random();
                string tempname;

                popupBox("Status:");

                Console.SetCursorPosition(r.SCREENMIN + 1, r.SCREENMIN + 4);
                tempname = randomStatName("strength", rdm.Next(5));
                Console.Write(tempname + ": " + r.pc.strength);
                Console.SetCursorPosition(r.SCREENMIN + 1, r.SCREENMIN + 5);
                tempname = randomStatName("agility", rdm.Next(5));
                Console.Write(tempname + ": " + r.pc.agility);
                Console.SetCursorPosition(r.SCREENMIN + 1, r.SCREENMIN + 6);
                tempname = randomStatName("magic", rdm.Next(5));
                Console.Write(tempname + ": " + r.pc.magic);
                Console.SetCursorPosition(r.SCREENMIN + 1, r.SCREENMIN + 7);
                tempname = randomStatName("stamina", rdm.Next(5));
                Console.Write(tempname + ": " + r.pc.stamina);
            }


            // When the menu's been rendered, enter into a command loop which
            // will dictate what keys the user can press, this is independant to
            // the main command loop
            while (menuRunning)
            {
                // Temporary variable to detect keystroke
                ConsoleKey inputTemp;
                inputTemp = Console.ReadKey().Key;

                // Start of command switch, parses keystrokes
                switch (inputTemp)
                {
                    case ConsoleKey.B:
                        menuRunning = false;
                        ScreenBuffer.initBuffer();
                        break;

                    default:
                        break;
                }
            }
            
            // When exiting the menu, clear the screen and load the last frame
            // stored in the screenBuffer list, no need to reload the buffer
            Console.Clear();
            ScreenBuffer.drawBuffer();
        }


        public static string randomStatName(string statname, int randnum)
        {

            if (statname == "stamina")
            {
                if (randnum == 1)
                {
                    return "Stamina";
                }
                else if (randnum == 2)
                {
                    return "Burliness";
                }
                else if (randnum == 3)
                {
                    return "Hench";
                }
                else if (randnum == 4)
                {
                    return "Fatness";
                }
                else if (randnum == 5)
                {
                    return "Stamulation";
                }
                else { return "Stamina"; }
            }
            if (statname == "agility")
            {
                if (randnum == 1)
                {
                    return "Agility";
                }
                else if (randnum == 2)
                {
                    return "Deftness";
                }
                else if (randnum == 3)
                {
                    return "Jumpability";
                }
                else if (randnum == 4)
                {
                    return "Moxie";
                }
                else if (randnum == 5)
                {
                    return "Slinkyness";
                }
                else { return "Agility"; }
            }
            if (statname == "magic")
            {
                if (randnum == 1)
                {
                    return "Magic";
                }
                else if (randnum == 2)
                {
                    return "Wizardlyness";
                }
                else if (randnum == 3)
                {
                    return "Kaboom";
                }
                else if (randnum == 4)
                {
                    return "Fizzlebang";
                }
                else if (randnum == 5)
                {
                    return "Robe likelyness";
                }
                else { return "Magic"; }
            }
            if (statname == "strength")
            {
                if (randnum == 1)
                {
                    return "Strength";
                }
                else if (randnum == 2)
                {
                    return "Gun show";
                }
                else if (randnum == 3)
                {
                    return "Flex";
                }
                else if (randnum == 4)
                {
                    return "GRRRRRR";
                }
                else if (randnum == 5)
                {
                    return "Anger";
                }
                else { return "Strength"; }
            }
            else
            {
                return "whoops!";
            }
        }

        // Welcome to the clumsiest clusterfuck in all my code!
        // This works, for now, but isn't very elegant at all. This creates
        // a dynamic popup box in the top left of the screen, sized based on
        // the length of the string "message" which is fed to it.
        public static void popupBox(string message)
        {
            // Clear the console window totally
            Console.Clear();
            // Put up the UI borders and such
            drawUI();
            // Clear the popup list for the new shit. The popup list
            // probably isn't necessary at all and i should offload this
            // to the screenBuffer or ui list items, but hey, nobody's
            // perfect!
            popup.Clear();

            // Create the top parts of the box, width is based on the message
            // variable's string length
            popup.Add(new UIItem(r.SCREENMIN+1, r.SCREENMIN, '╔'));
            for (int i = r.SCREENMIN+2; i < message.Length+5; i++)
            {
                popup.Add(new UIItem(i, r.SCREENMIN, '═'));
            }
            popup.Add(new UIItem(message.Length+5,r.SCREENMIN, '╗'));

            // Add the sides, again based on the string length
            popup.Add(new UIItem(r.SCREENMIN + 1, r.SCREENMIN + 1, '║'));
            popup.Add(new UIItem(message.Length + 5, r.SCREENMIN + 1, '║'));

            // Add the bottom parts to the popup box list
            popup.Add(new UIItem(r.SCREENMIN + 1, r.SCREENMIN+2, '╚'));
            for (int i = r.SCREENMIN + 2; i < message.Length + 5; i++)
            {
                popup.Add(new UIItem(i, r.SCREENMIN+2, '═'));
            }
            popup.Add(new UIItem(message.Length + 5, r.SCREENMIN+2, '╝'));

            // Take all those lovely new added pieces and render them all 
            // in one pass
            foreach (UIItem item in popup)
            {
                Console.SetCursorPosition(item.uiX, item.uiY);
                Console.Write(item.uiChar);
            }

            // Position the cursor for just inside the box and write the
            // message argument's contents
            Console.SetCursorPosition(r.SCREENMIN+3, r.SCREENMIN+1);
            Console.Write(message);

            // Draw the text in the lower right showing the key to press
            // to exit the menu
            Console.SetCursorPosition(r.SCREENX -6, r.SCREENY);
            Console.Write("(B)ack");

            uiCursor();
        }

        public static void uiCursor()
        {
            Console.SetCursorPosition(r.SCREENMIN - 1, r.SCREENY + 4);
            Console.Write("> ");
        }


        // This is called originally to feed the borders of the window into
        // it's own list object, will only be called when the game is initialised
        // or if anything substantial has changed to it. As it stands, it's only
        // used once at the start of the game
        public static void generateUI()
        {
            // Create a new list for the ui
            ui = new List<UIItem>();

            // Add the top part of the UI to the list item
            ui.Add(new UIItem(r.SCREENMIN - 1, r.SCREENMIN-1, '╔'));
            for (int i = r.SCREENMIN; i <= r.SCREENX; i++)
            {
                ui.Add(new UIItem(i, r.SCREENMIN-1, '═'));
            }
            ui.Add(new UIItem(r.SCREENX+1, r.SCREENMIN-1, '╗'));

            // Sidebars
            for (int i = r.SCREENMIN; i <= r.SCREENY; i++)
            {
                ui.Add(new UIItem(r.SCREENMIN - 1, i, '║'));
                ui.Add(new UIItem(r.SCREENX + 1, i, '║'));
            }

            // Bottom Box, top line
            ui.Add(new UIItem(r.SCREENMIN - 1, r.SCREENY + 1, '╠'));
            for (int i = r.SCREENMIN; i <= r.SCREENX; i++)
            {
                ui.Add(new UIItem(i, r.SCREENY + 1, '═'));
            }
            ui.Add(new UIItem(r.SCREENX + 1, r.SCREENY + 1, '╣'));

            // Bottom box, middle line
            ui.Add(new UIItem(r.SCREENMIN - 1, r.SCREENY + 2, '║'));
            for (int i = r.SCREENMIN; i <= r.SCREENX; i++)
            {
                ui.Add(new UIItem(i, r.SCREENY + 2, ' '));
            }
            ui.Add(new UIItem(r.SCREENX + 1, r.SCREENY + 2, '║'));

            // Bottom box, bottom line
            ui.Add(new UIItem(r.SCREENMIN - 1, r.SCREENY + 3, '╘'));
            for (int i = r.SCREENMIN; i <= r.SCREENX; i++)
            {
                ui.Add(new UIItem(i, r.SCREENY + 3, '═'));
            }
            ui.Add(new UIItem(r.SCREENX + 1, r.SCREENY + 3, '╛'));
        }
    }
    
    // Class generic to be used by all sorts of the UI elements
    // Virtually the same as any other list object, really, but
    // this one comes with it's own specific name!
    class UIItem
    {
        public int uiX, uiY;
        public char uiChar;

        public UIItem(int x, int y, char uichar)
        {
            uiX = x;
            uiY = y;
            uiChar = uichar;
        }
    }  
}